import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

import 'base_router_urls.dart';
import 'context_provider.dart';
import 'router_observer.dart';

class RouterUtils {
  RouterUtils._();

  static RouterUtils? _instance;

  static RouterUtils get instance => _instance ??= RouterUtils._();

  bool isLoginPageLaunched = false;

  ///将给定位置推送到页面堆栈上
  Future<T?> push<T extends Object?>(String routePath, {Object? extra}) async {
    if (ContextProvider.context != null) {
      if (_checkIsNotLoginPageLaunchDuplicated(routePath)) {
        return GoRouter.of(ContextProvider.context!).push<T>(routePath, extra: extra);
      }
    }
    return null;
  }

  ///替换页面堆栈的最顶层页面，但始终使用新的页面键
  Future<T?> pushReplacement<T extends Object?>(String routePath, {Object? extra}) async {
    if (ContextProvider.context != null) {
      if (_checkIsNotLoginPageLaunchDuplicated(routePath)) {
        return GoRouter.of(ContextProvider.context!).pushReplacement(routePath, extra: extra);
      }
    }
    return null;
  }

  Future<void> go(String routePath, {Object? extra}) async {
    if (ContextProvider.context != null) {
      if (_checkIsNotLoginPageLaunchDuplicated(routePath)) {
        return GoRouter.of(ContextProvider.context!).go(routePath, extra: extra);
      }
    }
    return;
  }

  ///将页面堆栈的最顶层页面替换为给定页面，但将其视为同一页面
  Future<T?> replace<T>(String routePath, {Object? extra}) async {
    if (ContextProvider.context != null) {
      if (_checkIsNotLoginPageLaunchDuplicated(routePath)) {
        return GoRouter.of(ContextProvider.context!).replace(routePath, extra: extra);
      }
    }
    return null;
  }

  /// like Navigator.pushAndRemoveUntil(context, newRouteName, (route) => false)
  Future<T?> replaceAndRemoveUntil<T>(String routePath, RoutePredicate removePredicate, {Object? extra}) async {
    if (ContextProvider.context != null) {
      while ((canPop() && removePredicate(routerObserver.top()))) {
        pop();
      }

      if (_checkIsNotLoginPageLaunchDuplicated(routePath)) {
        return replace(routePath, extra: extra);
      }
    }

    return null;
  }

  /// 检查确认不是登录页重复运行，保证登录页永远只有一个实例
  bool _checkIsNotLoginPageLaunchDuplicated(String routePath) {
    if (BaseRoutersUrls.signIn == routePath) {
      if (isLoginPageLaunched) {
        return false;
      }

      isLoginPageLaunched = true;
    }

    return true;
  }

  ///获取目标路由的上一个页面路由
  Route<dynamic>? beforeOf(String routePath) {
    if (ContextProvider.context != null) {
      return routerObserver.beforeOf(routePath);
    }
    return null;
  }

  ///获取当前页面
  Route<dynamic>? top() {
    if (ContextProvider.context != null) {
      return routerObserver.top();
    }
    return null;
  }

  /*
  * 场景举例(不是我们的现有业务): 一级页面->商城首页->商品详情->下单页->收银台页->付款成功页.
  * 如果收银台付款成功，则需要跳转到付款成功页面, 并将商品详情-下单页-收银台页全部移除, 直接回到A(商城首页), 则可使用以下方法
  * 使用方式: 在D页面调用pushAndRemoveUntil, routePath传入付款成功页(要去哪里)的路由, 入untilRoutePath传入商城首页(回到哪里)的路由
  * */
  Future<T?> pushAndRemoveUntil<T>(String routePath, String untilRoutePath, {Object? extra}) async {
    if (ContextProvider.context != null) {
      popUntil(untilRoutePath);
      return push(routePath, extra: extra);
    }
    return null;
  }

  popUntil(String untilRoutePath) {
    while ((canPop() && routerObserver.top().settings.name != untilRoutePath)) {
      pop();
    }
  }

  bool canPop() {
    if (ContextProvider.context != null) {
      return GoRouter.of(ContextProvider.context!).canPop();
    }

    return false;
  }

  ///弹出页面
  pop<T extends Object?>([T? result]) {
    if (ContextProvider.context != null) {
      if (ContextProvider.context!.canPop()) {
        ContextProvider.context!.pop(result);
      }
    }
  }

  /// 回到首页的方法(不推荐, 可能会有问题)
  Future<void> backToHome({Object? extra}) async {
    if (ContextProvider.context != null) {
      // 清除堆栈并回到首页
      await pushAndRemoveUntil(BaseRoutersUrls.home, BaseRoutersUrls.home, extra: extra);
    }
  }

  /// 返回到首页(推荐)
  popToHome() {
    while ((canPop())) {
      pop();
    }
  }
}
